#include "func.h"

int main(int argc,char *argv[])
{
    ARGS_CHECK(argc,3);
    int sock_fd=socket(AF_INET,SOCK_STREAM,0);
    ERROR_CHECK(sock_fd,-1,"socket");
    struct sockaddr_in serAddr;
    serAddr.sin_family=AF_INET;
    serAddr.sin_addr.s_addr=inet_addr(argv[1]);
    serAddr.sin_port=htons(atoi(argv[2]));
    int ret;
    ret=bind(sock_fd,(struct sockaddr *)&serAddr,sizeof(serAddr));
    ERROR_CHECK(ret,-1,"bind");
    listen(sock_fd,10);



    //开始用epoll
    int epfd=epoll_create(1);
    struct epoll_event event;
    event.data.fd=STDIN_FILENO;
    event.events=EPOLLIN;
    ret=epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&event);
    ERROR_CHECK(ret,-1,"epoll_ctl");

    event.data.fd=sock_fd;
    event.events=EPOLLIN;
    ret=epoll_ctl(epfd,EPOLL_CTL_ADD,sock_fd,&event);
    ERROR_CHECK(ret,-1,"epoll_ctl");
    struct epoll_event evs[3];

    struct sockaddr_in clientAddr;
    int addrLen,new_fd;
    int ready_fd_num,i;
    char buf[1000]={0};
    while (1)
    {
        ready_fd_num=epoll_wait(epfd,evs,3,-1);
        for(i=0;i<ready_fd_num;i++)
        {
            //sock_fd可读、代表有人链接了
            if(evs[i].data.fd==sock_fd)
            {
                addrLen=sizeof(clientAddr);
                new_fd=accept(sock_fd,(struct sockaddr *)&clientAddr,&addrLen);
                ERROR_CHECK(new_fd,-1,"accept");
                printf("ip=%s,port=%d connect\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
                event.data.fd=new_fd;
                event.events=EPOLLIN;
                ret=epoll_ctl(epfd,EPOLL_CTL_ADD,new_fd,&event);
                ERROR_CHECK(ret,-1,"epoll_ctl");
            }else if(evs[i].data.fd==STDIN_FILENO)
            {
                memset(buf,0,sizeof(buf));
                read(STDIN_FILENO,buf,sizeof(buf));
                send(new_fd,buf,strlen(buf)-1,0);
            }else if(evs[i].data.fd==new_fd)
            {
                memset(buf,0,sizeof(buf));
                ret=recv(new_fd,buf,sizeof(buf),0);
                if(0==ret)
                {
                    printf("client closed\n");
                    //删除客户端的描述符、避免疯狂打印
                    epoll_ctl(epfd,EPOLL_CTL_DEL,new_fd,0);
                    break;
                }
                printf("%s\n",buf);
            }
        }
    }
    close(new_fd);
    close(sock_fd);
    return 0;
}